﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Argos.Data.Model;
using Argos.Scheduling;
using System.Workflow.Runtime.Hosting;

namespace Argos.WorkflowServices
{
	/// <summary>
	/// A base implementation of the <see cref="IStorageService"/> interface.
	/// </summary>
	/// <remarks>
	/// Developers must extend this class in order to provide a bridge between
	/// Argos monitoring workflows and the data storage used by the hosting process.
	/// </remarks>
	public abstract class StorageServiceBase : WorkflowRuntimeService , IStorageService
	{

		#region #ctor: protected StorageServiceBase()

		/// <summary>
		/// Creates a new instance of the class.
		/// </summary>
		protected StorageServiceBase() { }

		#endregion



		#region public virtual MessageDeliveryRoute GetMessageDeliveryRouteBackup(Guid routeId)

		/// <summary>
		/// When overridden in a class, returns the backup route for the given message
		/// delivery route.
		/// </summary>
		/// <param name="routeId">The ID of the route for which to return the backup route.</param>
		public virtual MessageDeliveryRoute GetMessageDeliveryRouteBackup(Guid routeId)
		{
			return null;
		}

		#endregion

		#region public virtual MessageDeliveryRoute GetRecipientDeliveryRoute(Guid recipientId)

		/// <summary>
		/// When overridden in a class, returns the delivery route for the given recipient.
		/// </summary>
		/// <param name="recipientId">The ID of the recipient for which to return the message delivery route.</param>
		public virtual MessageDeliveryRoute GetRecipientDeliveryRoute(Guid recipientId)
		{
			return null;
		}

		#endregion
		
		#region public virtual List<Recipient> GetRecipients(Guid targetId, AlertTypes alertType)

		/// <summary>
		/// When overridden in a class, returns a list of recipients for the given target and type of alert.
		/// </summary>
		/// <param name="targetId">The ID of the target whose recipients to return.</param>
		/// <param name="alertType">The type of alert for which to return the recipients.</param>
		public virtual List<Recipient> GetRecipients(Guid targetId, AlertTypes alertType)
		{
			return new List<Recipient>();
		}

		#endregion
		
		#region public virtual Target GetTarget(Guid targetId)

		/// <summary>
		/// When overridden in a class, returns the target with the given ID.
		/// </summary>
		/// <param name="targetId">The ID of the target to return.</param>
		/// <returns>
		/// Returns the target with the given ID or null if the target was not found.
		/// </returns>
		/// <remarks>
		/// An implementation of this method must not throw an exception if the given target was not found.
		/// </remarks>
		public virtual Target GetTarget(Guid targetId)
		{
			return null;
		}

		#endregion

		public virtual List<Schedule> GetTargetActiveSchedules(Guid targetId)
		{
			return new List<Schedule>(new Schedule[] { Schedule.Always });
		}

		public virtual List<Schedule> GetTargetBreakSchedules(Guid targetId)
		{
			return new List<Schedule>(new Schedule[] { Schedule.Never });
		}

		#region public virtual Test GetTargetTest(Guid targetId)

		/// <summary>
		/// When overridden in a class, returns the test for the target with the given ID.
		/// </summary>
		/// <param name="targetId">The ID of the target whose test to return.</param>
		/// <returns>
		/// Returns the test or null if the target or test was not found.
		/// </returns>
		/// <remarks>
		/// An implementation of this method must not throw an exception if the given target or test was not found.
		/// </remarks>
		public virtual Test GetTargetTest(Guid targetId)
		{
			Target t = this.GetTarget(targetId);
			if (null != t)
				return t.Test;

			return null;
		}

		#endregion

		#region public virtual void StoreTestState(Guid targetId, object testState)

		/// <summary>
		/// When overridden in a class, stores the test state for the given target.
		/// </summary>
		/// <param name="targetId">The ID of the target whose test state to store.</param>
		/// <param name="testState">The test state to store.</param>
		public virtual void StoreTestState(Guid targetId, object testState)
		{
		}

		#endregion

	}
}
